package com.seven.smartsnmp.discover.service;


import com.seven.smartsnmp.config.DiscoverConfig;
import com.seven.smartsnmp.discover.DeviceInfo;
import com.seven.smartsnmp.discover.DeviceTypeInfo;
import com.seven.smartsnmp.discover.PortInfo;
import com.seven.smartsnmp.mib.MibMacIP;
import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author seven
 * @create 2019-06-17 13:35
 **/
public class DeviceInfoManager {


    public CopyOnWriteArrayList<DeviceInfo> allDeviceList;
    public List<DeviceInfo> switchList = new CopyOnWriteArrayList<>();
    public HashMap<String, DeviceInfo> macDeviceMap = new HashMap();
    public Map<String, String> allMacIpTable = new HashMap();

    public DeviceInfoManager(CopyOnWriteArrayList<DeviceInfo> deviceInfos) {
        System.out.println("开始装载初始化分析数据......：" + new Timestamp(System.currentTimeMillis()));
        this.allDeviceList = deviceInfos;
        this.initMacInfo();
        this.initDeviceGroupInfo();
        this.initPortSubDevices();
        System.out.println("分析数据初始化完毕!：" + new Timestamp(System.currentTimeMillis()));
    }

    /**
     * 初始化mac ip
     * 初始化 mac 设备
     */
    private void initMacInfo() {
        Iterator devIt = this.allDeviceList.iterator();
        while (devIt.hasNext()) {
            DeviceInfo deviceInfo = (DeviceInfo) devIt.next();
            String deviceMAC = deviceInfo.getDeviceMAC();
            List deviceMacList = deviceInfo.getDeviceMacList();
            List macIPList = deviceInfo.getMibMacIPList();
            Iterator macIpIt = macIPList.iterator();
            while (macIpIt.hasNext()) {
                MibMacIP macIP = (MibMacIP) macIpIt.next();
                this.allMacIpTable.put(macIP.getIpNetToMediaPhysAddress(), macIP.getIpNetToMediaNetAddress());
            }
            Iterator macIt = deviceMacList.iterator();
            while (macIt.hasNext()) {
                String devMac = (String) macIt.next();
                this.allMacIpTable.put(devMac, deviceInfo.getDeviceIP());
                this.macDeviceMap.put(devMac, deviceInfo);
            }
            if (StringUtils.isNotBlank(deviceMAC)) {
                this.allMacIpTable.put(deviceMAC, deviceInfo.getDeviceIP());
                this.macDeviceMap.put(deviceMAC, deviceInfo);
            }
        }
        System.out.println("系统中全部MAC地址和IP地址对应关系如下：");
        Set macIpSet = this.allMacIpTable.entrySet();
        Iterator macIpIt = macIpSet.iterator();
        while (macIpIt.hasNext()) {
            Map.Entry entry = (Map.Entry) macIpIt.next();
            System.out.println("MAC地址：" + (String) entry.getKey() + ",对应的IP：" + (String) entry.getValue());
        }

    }

    /**
     * 对设备进行分组
     * 区分交换机设备
     * 路由设备
     */
    private void initDeviceGroupInfo() {
        System.out.println("开始对设备进行交换机和普通设备分类");
        try {
            Iterator infoIterator = this.allDeviceList.iterator();
            while (infoIterator.hasNext()) {
                DeviceInfo deviceInfo = (DeviceInfo) infoIterator.next();
                if (deviceInfo.getDeviceType() == DeviceTypeInfo.SwitchType ||
                        deviceInfo.getDeviceType() == DeviceTypeInfo.RouterSwitchType) {
                    if (deviceInfo.getdTpFdbTableList().size() > 0) {
                        System.out.println(deviceInfo.getDeviceIP() + "有连接关系信息，按交换机/三层交换机交换机分类");
                        this.switchList.add(deviceInfo);
                    } else {
                        System.out.println(deviceInfo.getDeviceIP() + "没有连接关系信息，按终端设备处理");
                    }
                }
            }
            System.out.println("所有设备分类完毕，具备连接基础信息的设备:" + this.switchList.size() + "个");
        } catch (Exception exception) {
            exception.printStackTrace();
        }

    }

    /**
     *
     */
    private void initPortSubDevices() {
        try {
            System.out.println("=============================");
            System.out.println("开始初始化交换机端口下挂设备信息.....");
            Iterator switchIt = this.switchList.iterator();
            while (switchIt.hasNext()) {
                DeviceInfo deviceInfo = (DeviceInfo) switchIt.next();
                if (DiscoverConfig.isDebug) {
                    System.out.println("=============================");
                }
                //全部的端口信息
                Iterator iterator = deviceInfo.getPortInfoList().iterator();

                while (iterator.hasNext()) {
                    PortInfo portInfo = (PortInfo) iterator.next();
                    this.initPortInfo(portInfo);
                }
            }
            System.out.println("初始化交换机端口下挂设备信息完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public DeviceInfo getDeviceInfoFromDeviceListByIp(String ip) {
        Iterator iterator = this.allDeviceList.iterator();

        while (iterator.hasNext()) {
            DeviceInfo deviceInfo = (DeviceInfo) iterator.next();
            if (deviceInfo.getDeviceIP().equals(ip)) {
                return deviceInfo;
            }
        }
        return null;
    }

    public DeviceInfo getDeviceInfoByMAC(String mac) {
        return mac != null && !mac.equals("") ? (DeviceInfo) this.macDeviceMap.get(mac) : null;
    }

    public String getIPOfMac(String ip) {
        return (String) this.allMacIpTable.get(ip);
    }

    //初始化端口信息
    private void initPortInfo(PortInfo portInfo) {
        List portMacList = portInfo.portMacList;
        Iterator it = portMacList.iterator();
        while (it.hasNext()) {
            String mac = (String) it.next();
            DeviceInfo deviceInfo = this.getDeviceInfoByMAC(mac);
            if (deviceInfo != null && !deviceInfo.equals(portInfo.device) &&
                    !portInfo.subDeviceList.contains(deviceInfo)) {
                portInfo.subDeviceList.add(deviceInfo);
                if (DiscoverConfig.isDebug) {
                    System.out.println(portInfo + ",下挂设备之一" + deviceInfo);
                }
            }
        }

    }
}
